package com.lian.hope.controller;

import com.lian.hope.model.dto.*;
import com.lian.hope.model.po.Users;
import com.lian.hope.model.vo.*;
import com.lian.hope.service.DynamicService;
import com.lian.hope.service.UsersService;
import com.lian.hope.utils.JwtUtil;
import com.lian.hope.utils.RedisUtil;
import com.lian.hope.utils.Result;
import com.lian.hope.utils.SmsSenderUtil;
import com.lian.hope.websocket.WebSocketServer;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.Null;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/users")
@Slf4j
@Tag(name = "用户模块相关接口", description = "用户模块相关接口")
@RequiredArgsConstructor
public class UsersController {
    private final UsersService usersService;
    private final DynamicService dynamicService;
    private final WebSocketServer webSocketServer;
    private final RedisUtil redisUtil;
    private final SmsSenderUtil smsSenderUtil;

    @Operation(summary = "微信授权登录")
    @PostMapping("/login/wechat")
    public Result<String> authWechatLogin(@RequestBody UsersAuthDTO usersAuthDTO) {
        String token = usersService.authWechatLogin(usersAuthDTO);

        return Result.success(token);
    }

    @Operation(summary = "一键登录管理员账号")
    @PostMapping("/login/admin")
    public Result<String> loginAdminUser() {
        String token = usersService.loginAdminUser();
        return Result.success(token);

    }

    @Operation(summary = "更新当前登录用户的信息")
    @PutMapping
    public Result<Null> updateUsersById(@RequestBody UserDTO userDTO,
        @RequestHeader("Authorization") String Authorization) {
        Map<String, Object> claims = JwtUtil.parseToken(Authorization);
        log.info("claims:{}", claims);
        Long userId = Long.parseLong(claims.get("userId").toString());

        usersService.updateUsersById(userDTO, userId);
        return Result.success();
    }

    @Operation(summary = "更新用户积分")
    @PutMapping("/points/{points}")
    public Result<Boolean> updateUserPointsById(
        @Parameter(description = "添加的积分数量", required = true) @PathVariable Integer points,
        @RequestHeader String Authorization) {
        Map<String, Object> claims = JwtUtil.parseToken(Authorization);
        Long userId = Long.parseLong(claims.get("userId").toString());
        Boolean isSignIn = usersService.updateUserPointsById(points, userId);
        if (isSignIn) {
            return Result.success(true);
        } else {
            log.info("签到失败");
            return Result.success(false);
        }
    }

    @Operation(summary = "获取当前用户的动态")
    @GetMapping("/dynamics")
    public Result<List<DynamicVO>> listDynamicByUserId(@RequestHeader String Authorization) {
        Map<String, Object> claims = JwtUtil.parseToken(Authorization);
        Long userId = Long.parseLong(claims.get("userId").toString());

        List<DynamicVO> dynamicList = dynamicService.listDynamicByUserId(userId);
        return Result.success(dynamicList);
    }

    @Operation(summary = "获取当前用户的项目")
    @GetMapping("/projects")
    public Result<List<ProjectsVO>> listDonationsProjectsByUserId(@RequestHeader String Authorization) {
        Map<String, Object> claims = JwtUtil.parseToken(Authorization);
        Long userId = Long.parseLong(claims.get("userId").toString());
        List<ProjectsVO> projectsVOS = usersService.listDonationsProjectsByUserId(userId);
        return Result.success(projectsVOS);
    }

    @GetMapping("/activities")
    @Operation(summary = "获取当前用户的报名的活动")
    public Result<List<VolunteerActivitiesVO>> listRegisterActivities(@RequestHeader String Authorization) {
        Map<String, Object> claims = JwtUtil.parseToken(Authorization);
        Long userId = Long.parseLong(claims.get("userId").toString());
        log.info("userId:{}", userId);

        List<VolunteerActivitiesVO> volunteerActivitiesVOS = usersService.listRegisterActivitiesByUserId(userId);
        log.info("volunteerActivitiesVOS:{}", volunteerActivitiesVOS);

        return Result.success(volunteerActivitiesVOS);

    }

    @Operation(summary = "获取当前用户的信息")
    @GetMapping("/my")
    public Result<UsersVO> getMeInfoById(@RequestHeader String Authorization) {
        Map<String, Object> claims = JwtUtil.parseToken(Authorization);
        Long userId = Long.parseLong(claims.get("userId").toString());
        UsersVO usersVO = usersService.getUserInfoById(userId);

        return Result.success(usersVO);
    }

    @Operation(summary = "根据用户id获取用户信息")
    @GetMapping("/{userId}")
    public Result<UsersVO> getUserInfoById(@PathVariable Long userId) {
        UsersVO usersVO = usersService.getUserInfoById(userId);

        log.info("usersVO:{}", usersVO);
        return Result.success(usersVO);
    }

    @Operation(summary = "根据用户角色获取用户可用的操作项")
    @GetMapping("/operate-list")
    public Result<List<OperateVO>> getUserOperateByRole(@RequestHeader String Authorization) {
        Map<String, Object> claims = JwtUtil.parseToken(Authorization);
        Long userId = Long.parseLong(claims.get("userId").toString());
        log.info("userId:{}", userId);

        List<OperateVO> operateVOS = usersService.getUserOperateByRole(userId);

        return Result.success(operateVOS);
    }

    @Operation(summary = "发送短信验证码")
    @PostMapping("/send-sms")
    public Result<String> sendSms(@RequestBody SendSmsDTO sendSmsDTO) {

        /** 是否已存在该验证码*/
        Boolean isExist = redisUtil.hasKey(sendSmsDTO.getPhoneNumber());
        if (isExist)
            return Result.error("60秒内不能重复发送");

        // 发送验证码
                String code = smsSenderUtil.sendSms(sendSmsDTO.getPhoneNumber());

        // 设置验证码 并设置过期时间
        redisUtil.set(sendSmsDTO.getPhoneNumber(), code, 60);

        return Result.success("发送成功");
    }

    /**
     * 短信验证码登录
     *
     * @param smsLoginDTO
     * @return
     */
    @Operation(summary = "短信验证码登录")
    @PostMapping("/login/sms")
    public Result<String> smsLogin(@RequestBody SmsLoginDTO smsLoginDTO) {
        if (smsLoginDTO.getCode() == null)
            return Result.error("请填写验证码");
        // 从redis中获取验证码
        String code = (String)redisUtil.get(smsLoginDTO.getPhoneNumber());
        if (code == null) {
            return Result.error("请先发送验证码");
        }
        if (!code.equals(smsLoginDTO.getCode())) {
            return Result.error("验证码错误");
        }

        String token = usersService.smsLogin(smsLoginDTO.getPhoneNumber(), smsLoginDTO.getWxCode());
        // 登录成功之后 从redis中删除验证码
        redisUtil.delete(smsLoginDTO.getPhoneNumber());
        return Result.success(token);
    }

}
